﻿Imports System
Imports System.Drawing
Imports System.Runtime.CompilerServices
Imports System.Windows.Forms

Namespace System.Workflow.ComponentModel.Design
    Friend Class DragRectangleMessageFilter
        Inherits WorkflowDesignerMessageFilter
        ' Events
        Friend Custom Event DragComplete As EventHandler

        ' Methods
        Friend Sub New()
        End Sub

        Protected Overrides Sub Dispose(ByVal disposing As Boolean)
            Try 
                Me.DragStarted = False
            Finally
                MyBase.Dispose(disposing)
            End Try
        End Sub

        Protected Overrides Function OnKeyDown(ByVal eventArgs As KeyEventArgs) As Boolean
            If (eventArgs.KeyValue = &H1B) Then
                Me.DragStarted = False
            End If
            Return False
        End Function

        Protected Overrides Function OnMouseCaptureChanged() As Boolean
            Me.DragStarted = False
            Return False
        End Function

        Protected Overrides Function OnMouseDown(ByVal eventArgs As MouseEventArgs) As Boolean
            If (eventArgs.Button = MouseButtons.Left) Then
                Me.startDrag = Me.endDrag = MyBase.ParentView.ClientPointToLogical(New Point(eventArgs.X, eventArgs.Y))
            End If
            Return False
        End Function

        Protected Overrides Function OnMouseMove(ByVal eventArgs As MouseEventArgs) As Boolean
            Dim parentView As WorkflowView = MyBase.ParentView
            Dim point As Point = parentView.ClientPointToLogical(New Point(eventArgs.X, eventArgs.Y))
            Dim num As Single = ((2! / CSng(parentView.Zoom)) * 100!)
            If ((Not Me.dragStarted AndAlso ((eventArgs.Button And MouseButtons.Left) > MouseButtons.None)) AndAlso ((Math.Abs(CInt((Me.startDrag.X - point.X))) > CInt((num * SystemInformation.DragSize.Width))) OrElse (Math.Abs(CInt((Me.startDrag.Y - point.Y))) > CInt((num * SystemInformation.DragSize.Height))))) Then
                Me.DragStarted = True
            End If
            If Me.dragStarted Then
                If Not Me.DragRectangle.IsEmpty Then
                    parentView.InvalidateLogicalRectangle(Me.DragRectangle)
                End If
                Me.endDrag = point
                If Not Me.DragRectangle.IsEmpty Then
                    parentView.InvalidateLogicalRectangle(Me.DragRectangle)
                End If
            End If
            Return Me.dragStarted
        End Function

        Protected Overrides Function OnMouseUp(ByVal eventArgs As MouseEventArgs) As Boolean
            If Not Me.dragStarted Then
                Return False
            End If
            Dim parentView As WorkflowView = MyBase.ParentView
            If Not Me.DragRectangle.IsEmpty Then
                parentView.InvalidateLogicalRectangle(Me.DragRectangle)
            End If
            Me.endDrag = parentView.ClientPointToLogical(New Point(eventArgs.X, eventArgs.Y))
            Me.DragStarted = False
            If (Not Me.DragComplete Is Nothing) Then
                Me.DragComplete.Invoke(Me, EventArgs.Empty)
            End If
            Return True
        End Function

        Protected Overrides Function OnPaint(ByVal e As PaintEventArgs, ByVal viewPort As Rectangle, ByVal ambientTheme As AmbientTheme) As Boolean
            If Me.dragStarted Then
                [Using] brush As Brush = New SolidBrush(Color.FromArgb(10, ambientTheme.SelectionForeColor))
                    Dim dragRectangle As Rectangle = Me.DragRectangle
                    e.Graphics.FillRectangle(brush, dragRectangle.X, dragRectangle.Y, (dragRectangle.Width - 1), (dragRectangle.Height - 1))
                    e.Graphics.DrawRectangle(ambientTheme.SelectionForegroundPen, dragRectangle.X, dragRectangle.Y, (dragRectangle.Width - 1), (dragRectangle.Height - 1))
                End [Using]
            End If
            Return False
        End Function


        ' Properties
        Friend ReadOnly Property DragRectangle As Rectangle
            Get
                Return New Rectangle(Math.Min(Me.startDrag.X, Me.endDrag.X), Math.Min(Me.startDrag.Y, Me.endDrag.Y), Math.Abs(CInt((Me.endDrag.X - Me.startDrag.X))), Math.Abs(CInt((Me.endDrag.Y - Me.startDrag.Y))))
            End Get
        End Property

        Protected Property DragStarted As Boolean
            Get
                Return Me.dragStarted
            End Get
            Set(ByVal value As Boolean)
                If (Me.dragStarted <> value) Then
                    Dim parentView As WorkflowView = MyBase.ParentView
                    If value Then
                        Me.dragStarted = True
                        Me.previousCursor = parentView.Cursor
                        parentView.Cursor = Cursors.Cross
                        parentView.Capture = True
                    Else
                        parentView.Capture = False
                        Me.dragStarted = False
                        If (Not Me.previousCursor Is Nothing) Then
                            parentView.Cursor = Me.previousCursor
                        End If
                        If Not Me.DragRectangle.IsEmpty Then
                            parentView.InvalidateLogicalRectangle(Me.DragRectangle)
                        End If
                    End If
                End If
            End Set
        End Property


        ' Fields
        Private dragStarted As Boolean
        Private endDrag As Point = Point.Empty
        Private previousCursor As Cursor = Cursors.Default
        Private startDrag As Point = Point.Empty
    End Class
End Namespace

